package han.chensing.latos.game.container;

import java.lang.reflect.Method;
import java.util.ArrayDeque;

public class FakeContainer{
	private final ArrayDeque<CallEntry> entries;
	private final Class<?> proxyClass;
	private final Method[] methods;
	protected final Object object;
	
	public FakeContainer(Object o,int capacity){
		this.proxyClass=o.getClass();
		this.entries=new ArrayDeque<>(64);
		this.object=o;
		this.methods=new Method[capacity];
	}
	
	protected void registerAndDelayCall(
		int num,String name,Class<?>[] parameterTypes,
		Object... parameters){
		try{
			register(num,name,parameterTypes);
			CallEntry entry=new CallEntry();
			entry.num=num;
			entry.parameters=parameters;
			entries.offer(entry);
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	public void run(){
		CallEntry entry;
		while((entry=entries.poll())!=null){
			try{
				Method m=methods[entry.num];
				if(m==null)continue;
				m.setAccessible(true);
				m.invoke(object,entry.parameters);
			}catch(Exception e){
				e.printStackTrace();
			}
		}
	}
	
	private void register(int num,String name,Class<?>... parameterTypes) throws Exception{
		if (methods[num]!=null)return;
		methods[num]=proxyClass.getDeclaredMethod(name,parameterTypes==null?new Class<?>[]{}:parameterTypes);
	}
	
	public static class CallEntry{
		int num;
		Object[] parameters;
	}
}
